package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.Sign;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.utils.Pair;

import java.util.*;

/**
 * 同柱阵 Quarto
 */
public class QuartoRoom extends Room {

    private CacheSign cacheSign; //缓存标记
    private boolean dropped=true; //是否已经完成落子
    private int chosenRow =0,chosenCol=0; //对方选择的棋子
    private int[][] realGrids={
            {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},
            {-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1}};

    public QuartoRoom(String roomName) {
        super(roomName, "一款经典的小品新棋。", "同柱阵", GridsUtils.createEmptyGrids(6, 6), true, false);
        initChessBoardStyle();
    }

    //初始化背景样式，接着抄禽将棋（挨打）
    private void initChessBoardStyle() {
        List<Sign> chessboardStyle = new ArrayList<>();
        int row = curGrids.length;
        int col = curGrids[0].length;

        //将画布默认格子隐藏了
        chessboardStyle.add(new GroundSign(getIndex(0, 0), getIndex(row - 1, col - 1), ColorCost.TABLECLOTH_COLOR, ColorCost.TABLECLOTH_COLOR, 2.0f, 0, 0));

        //画棕棋盘颜色
        chessboardStyle.add(new GroundSign(getIndex(0, 0), getIndex(row - 1, col - 1), "#FFDD976D", "#FFC57555", 1f, 0, 0));

        //绘制底纹模拟木纹
        List<Integer> allIds = new ArrayList<>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                allIds.add(getIndex(i, j));
            }
        }
        FigureSign figure = FigureSign.makeBatchSingleFigure(allIds, "#99C57555");
        int version = 33;
        figure.setMidSideLine(1, 1, 1, 1, 1, 1, 1, 1); //还OK
        chessboardStyle.add(figure);

        //画半透明黑白相间的格子
        List<Integer> whiteGrids = new ArrayList<>();
        List<Integer> blackGrids = new ArrayList<>();
        for (int i = 1; i < row-1; i++) {
            for (int j = 1; j < col-1; j++) {
                int index = getIndex(i, j);
                if ((i + j) % 2 == 0) {
                    whiteGrids.add(index);
                }
                else {
                    blackGrids.add(index);
                }
            }
        }
        chessboardStyle.add(new ColorSign(blackGrids, "#BB333333"));
        chessboardStyle.add(new ColorSign(whiteGrids, "#BBDDDDDD"));

        //画棋盘格子线
        for (int i = 1; i < row; i++) {
            List<Pair<Integer, Integer>> nodes1 = new ArrayList<>();
            nodes1.add(new Pair<>(getIndex(i, 1), 0)); //起点
            nodes1.add(new Pair<>(getIndex(i, col - 2), 2)); //终点
            chessboardStyle.add(new PathSign(nodes1, "#FF000000", "#00000000", 1f, 0));
        }
        for (int j = 1; j < col; j++) {
            List<Pair<Integer, Integer>> nodes1 = new ArrayList<>();
            nodes1.add(new Pair<>(getIndex(1, j), 0)); //起点
            nodes1.add(new Pair<>(getIndex(row - 2, j), 6)); //终点
            chessboardStyle.add(new PathSign(nodes1, "#FF000000", "#00000000", 1f, 0));
        }

        //画棋盘外边框
        List<Pair<Integer, Integer>> nodes1 = new ArrayList<>();
        nodes1.add(new Pair<>(getIndex(1, 1), 0));
        nodes1.add(new Pair<>(getIndex(1, col - 2), 2));
        nodes1.add(new Pair<>(getIndex(row - 2, col - 2), 8));
        nodes1.add(new Pair<>(getIndex(row - 2, 1), 6));
        nodes1.add(new Pair<>(getIndex(1, 1), 0));
        nodes1.add(new Pair<>(getIndex(1, col - 2), 2));
        chessboardStyle.add(new PathSign(nodes1, "#FF000000", "#00000000", 1f, 0));

        //添加到缓存标记中
        cacheSign = new CacheSign(this, "background", version, true, chessboardStyle); //*** 修改背景样式记得改这里的版本号！！！
    }

    @Override
    public String getRuleText() {
        return "《同柱阵》\n\n" +
                "基本规则：\n游戏共进行8.5个回合(17手)，双方共享16枚棋子。\n"+
                "第1手，先手选择1枚棋子；\n第2手，后手将先手选择的棋子落在任意空格，然后再选择1枚棋子。\n" +
                "第3手，先手将后手选择的棋子落在任意空格，然后再选择1枚棋子；\n" +"依次类推，直至决出胜负或棋子用完。\n\n" +
                "胜负判断：\n棋子共有颜色、形状、字符颜色、字符型状4种属性，任何一种属性相同的棋子连4（横、竖、斜）即获胜。\n" +
                "若棋子用完而未决出胜负，则判和。";
    }

    @Override
    public String getCoordMode() {
        return "41411111";
    }

    @Override
    public CacheSign getCacheSignByName(String cacheName) {
        return cacheSign;
    }

    @Override
    public String getGameInfo() {
        //先全部初始化
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        signList.add(cacheSign);

        //这里需要绘制棋子
        int tmpPiece,type1,type2,type3,type4;
        String tmpName,tmpColour;
        for(int i=0;i<6;i++) for(int j=0;j<6;j++){
            tmpPiece=realGrids[i][j];
            if(tmpPiece==-1) {
                curGrids[i][j]=0; continue;}
            type1=tmpPiece%2; tmpPiece/=2;
            type2=tmpPiece%2; tmpPiece/=2;
            type3=tmpPiece%2; tmpPiece/=2;
            type4=tmpPiece%2;

            curGrids[i][j]=1+type1+type2*10; //黑白方圆
            tmpName=(type3==1)?"O":"X";
            tmpColour=(type4==1)?"#FFFF3838":"#FF00BFFF";
            this.signList.add(new TextSign(this.getIndex(i, j), tmpName, tmpColour));
        }
        if(chosenRow!=-1) //高亮对手选中的棋子
            this.signList.add(new GroundSign(getIndex(chosenRow, chosenCol), "#38BF7FFF", "#FF7F38BF", 1.0f, 3, 0));

        if(step==1) gameTip="请选择1枚棋子，由对方下回合落子。";
        else gameTip="对方已选择棋子，请落子。";

        return super.getGameInfo();
    }

    @Override
    protected void onStartPrepare() {
        step=1;
        initBoardAndPieces(); //重新创建初始布局的棋子
    }

    private void initBoardAndPieces() {
        for(int i=0;i<6;i++)
            for(int j=0;j<6;j++)
                realGrids[i][j]=-1;
        for(int k=0;k<4;k++){
            realGrids[0][1+k]=k;
            realGrids[1+k][5]=k+4;
            realGrids[5][4-k]=k+8;
            realGrids[4-k][0]=k+12;
        }
        //棋子编号为0~15，转写成4位二进制，每一位代表一种属性
        gameTip="请选择1枚棋子，由对方下回合落子。";

        noticeBlackMove();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        dropped = true;
        chosenRow = -1; chosenCol=-1;
    }

    @Override
    public void doRule(int row, int col, int value) {
        //System.out.printf("%d %d %d %d %d %b\n",step,row,col,realGrids[row][col],curGrids[row][col],dropped);
        if(dropped || step==1){ //选棋子给对方
            if(!(row==0 || row==5 || col==0 || col==5)) return;
            if(realGrids[row][col]==-1) return;
            chosenRow=row; chosenCol=col;
            dropped=false;
            step++;
            noticeAllRefreshGameInfo();
            if(value==1) noticeWhiteMove();
            else noticeBlackMove();
        }else{ //落子
            if(row==0 || row==5 || col==0 || col==5) return;
            if(realGrids[row][col]!=-1) return;
            realGrids[row][col]=realGrids[chosenRow][chosenCol];
            realGrids[chosenRow][chosenCol]=-1;
            chosenRow=chosenCol=-1;
            noticeAllRefreshGameInfo();
            checkOver(value);
            gameTip="请选择1枚棋子，由对方下回合落子。";
            dropped=true;
        }
    }

    /**
     * 判断游戏是否结束
     */
    private void checkOver(int side) {
        boolean gameOver = false;
        for (int i = 1; i < 5; i++) {
            if (checkIsRow(realGrids[i][1], realGrids[i][2], realGrids[i][3], realGrids[i][4]) ||
                    checkIsRow(realGrids[1][i], realGrids[2][i], realGrids[3][i], realGrids[4][i])) {
                gameOver = true;
                break;
            }
        }
        if (checkIsRow(realGrids[1][1], realGrids[2][2], realGrids[3][3], realGrids[4][4]) ||
                checkIsRow(realGrids[1][4], realGrids[2][3], realGrids[3][2], realGrids[4][1]))
            gameOver = true;
        if(gameOver) {
            if (side == 1) doOver(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执先手战胜" + player_white.getNickNameOrTemp());
            else doOver(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执后手战胜" + player_black.getNickNameOrTemp());
            gameTip="-1";
        }else if(step==17){ //平局
            doOver(WinMode.BOTH_DRAW, player_white.getNickNameOrTemp() + "与" + player_black.getNickNameOrTemp()+ "战平");
            gameTip="-1";
        }
    }

    /**
     * 检查这4枚棋子是否符合要求
     */
    private boolean checkIsRow(int a,int b,int c,int d) {
        if(a==-1 || b==-1 || c==-1 |d==-1) return false;
        for(int i=0;i<4;i++){
            if((a%2==b%2)&&(a%2==c%2)&&(a%2==d%2)) return true;
            a/=2; b/=2; c/=2; d/=2;
        }
        return false;
    }
}
